package com.stox.ui.javafx.charting.model.plot;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import com.stox.client.CachingBarClient;
import com.stox.dto.AbstractBar;
import com.stox.dto.AbstractModel;
import com.stox.dto.enumeration.Span;
import com.stox.dto.enumeration.SpanType;
import com.stox.ui.javafx.charting.model.enumeration.ChartType;
import com.stox.ui.javafx.charting.model.uiunit.AbstractPrimaryUiUnit;
import com.stox.ui.javafx.charting.view.ChartingView;
import com.stox.ui.javafx.charting.widget.PrimaryChart;

public abstract class AbstractPrimaryPlot<T extends AbstractBar, 
						W extends PrimaryChart<U>,
						V extends AbstractPrimaryUiUnit<T,W, V, U>, 
						U extends AbstractPrimaryPlot<T,W,V,U>> 
		extends AbstractPlot<T, W, V, U> {

	private ChartType chartType = ChartType.HLC;

	protected double volumeSum = 0;

	private Span span = null;
	
	private SpanType spanType = null;
	
	private boolean dataChanged = true;
	
	@Autowired
	private CachingBarClient barClient;
	
	public AbstractPrimaryPlot(AbstractModel model) {
		super(model);
	}

	public abstract void setVolumeData();
	
	@Override
	public void update() {
		super.update();
		ChartingView view = getChart().getChartingView();
		
		if(view.isAutoSpan() && view.getEndIndex() > getData().size()){
			view.setLoading(true);
			span = view.getSpan();
			Date start = null;
			int count = 0;
			if(getData().isEmpty()){
				start = view.getLastTreadingDate();
				count = view.getDefaultBars();
			}else{
				start = getData().get(getData().size() - 1).getDate();
				count = view.getAutoFetchSize();
			}
			
			List<T> bars = barClient.findByScripId(getModel().getId(), view.getSpanType(), start, count);
			int oldSize = getData().size();
			getData().addAll(bars);
			setData(getData());
			int newSize = getData().size();
			oldSize = (0 == oldSize ? newSize : oldSize);
			double highValue = view.getPrimaryChart().getRangeSlider().getHighValue();
			double lowValue = view.getPrimaryChart().getRangeSlider().getLowValue();
			double newHighValue = (highValue - lowValue)*oldSize/newSize;
			
			view.getPrimaryChart().getRangeSlider().setLowValue(0);
			view.setLoading(false);
			view.getPrimaryChart().getRangeSlider().setHighValue(newHighValue);
		}
		
		if(view.isAutoSpanType()){
			if(!getData().isEmpty() && !view.getSpanType().equals(spanType)){
				view.setLoading(true);
				spanType = view.getSpanType();
				Date start = getData().get(0).getDate();
				Date end = getData().get(getData().size() - 1).getDate();
				List<T> bars = barClient.findByScripId(getModel().getId(), spanType, start, end);
				setData(bars);
				view.updateZoom();
				view.setLoading(false);
			}
		}
		
		if(!view.getSpan().equals(span) || !view.getSpanType().equals(spanType)){
			view.setLoading(true);
			this.span = view.getSpan();
			this.spanType = view.getSpanType();
			
			Date start = view.getLastTreadingDate();
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(start);
			calendar.add(view.getSpan().getUnit(), -1*view.getSpan().getCount());
			List<T> bars = barClient.findByScripId(getModel().getId(), spanType, start, calendar.getTime());
			setData(bars);
			view.setLoading(false);
			view.update();
		}
	}
	
	@Override
	public List<V> getUiUnits() {
		return super.getUiUnits();
	}
	
	@Override
	public void reset() {
		super.reset();
		volumeSum = 0;
	}
	
	public ChartType getChartType() {
		return chartType;
	}

	public void setChartType(ChartType chartType) {
		this.chartType = chartType;
	}

	public double getVolumeSum() {
		return volumeSum;
	}

	@Override
	public void setData(List<T> data) {
		super.setData(data);
		setDataChanged(true);
		setVolumeData();
	}
	

	public boolean isDataChanged() {
		return dataChanged;
	}

	public void setDataChanged(boolean dataChanged) {
		this.dataChanged = dataChanged;
	}
	
}
